﻿using AutoMapper;
using Coldairarrow.Business.Cache;
using Coldairarrow.Entity;
using Coldairarrow.Entity.Base;
using Coldairarrow.Entity.Base_Manage;
using Coldairarrow.Entity.DTO;
using Coldairarrow.Entity.PB;
using Coldairarrow.IBusiness;
using Coldairarrow.Util;
using EFCore.Sharding;
using LinqKit;
using Microsoft.EntityFrameworkCore;
using Newtonsoft.Json;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Linq.Dynamic.Core;
using System.Linq.Expressions;
using System.Text;
using System.Threading.Tasks;

namespace Coldairarrow.Business.Base_Manage
{
    public partial class Base_UserBusiness : BaseBusiness<Base_User>, IBase_UserBusiness, ITransientDependency, IOperatorDept
    {
        readonly IOperator _operator;
        readonly IMapper _mapper;
        public Base_UserBusiness(
            IDbAccessor db,
            IBase_UserCache userCache,
            IOperator @operator,
            IMapper mapper
            )
            : base(db)
        {
            _userCache = userCache;
            _operator = @operator;
            _mapper = mapper;
        }
        IBase_UserCache _userCache { get; }
        protected override string _textField => "RealName";

        #region 外部接口
        public async Task AddUserExlAsync(List<Base_User> list)
        {
            await Db.InsertAsync<Base_User>(list);

        }
        public async Task AddUserRoleExlAsync(List<Base_UserRole> list)
        {
            await Db.InsertAsync<Base_UserRole>(list);

        }

        public async Task<PageResult<Base_UserDTO>> GetDataListAsync(PageInput<Base_UsersInputDTO> input)
        {
            Expression<Func<Base_User, Base_Department, Base_Department, Base_UserDTO>> select = (a, b, c) => new Base_UserDTO
            {
                DepartmentName = b.Name,
                SupplierId =b.SupplierId,
                FactoryName = c.Name,

            };
            var search = input.Search;
            select = select.BuildExtendSelectExpre();
            var q_User = search.all ? Db.GetIQueryable<Base_User>() : GetIQueryable();
            var q = from a in q_User.AsExpandable()
                    join b in Db.GetIQueryable<Base_Department>() on a.DepartmentId equals b.Id into ab
                    from b in ab.DefaultIfEmpty()
                    join c in Db.GetIQueryable<Base_Department>() on a.FactoryId equals c.Id into ac
                    from c in ac.DefaultIfEmpty()
                    select @select.Invoke(a, b, c);

            q = q.WhereIf(!search.userId.IsNullOrEmpty(), x => x.Id == search.userId);
            if (!search.keyword.IsNullOrEmpty())
            {
                var keyword = $"%{search.keyword}%";
                q = q.Where(x =>
                      EF.Functions.Like(x.UserName, keyword)
                      || EF.Functions.Like(x.RealName, keyword));
            }
            if (!search.DepartmentId.IsNullOrEmpty()) {
                q = q.Where(m=>m.DepartmentId==search.DepartmentId);
            }
            if (!search.Faid.IsNullOrEmpty()) {
                q = q.Where(m => m.UserCode == search.Faid);
            }
            var list = await q.GetPageResultAsync(input);

            await SetProperty(list.Data);

            return list;

            async Task SetProperty(List<Base_UserDTO> users)
            {
                //补充用户角色属性
                List<string> userIds = users.Select(x => x.Id).ToList();
                var userRoles = await (from a in Db.GetIQueryable<Base_UserRole>()
                                       join b in Db.GetIQueryable<Base_Role>() on a.RoleId equals b.Id
                                       where userIds.Contains(a.UserId)
                                       select new
                                       {
                                           a.UserId,
                                           RoleId = b.Id,
                                           b.RoleName
                                       }).ToListAsync();
                users.ForEach(aUser =>
                {
                    var roleList = userRoles.Where(x => x.UserId == aUser.Id);
                    aUser.RoleIdList = roleList.Select(x => x.RoleId).ToList();
                    aUser.RoleNameList = roleList.Select(x => x.RoleName).ToList();
                    //补充用户数据权限属性
                    aUser.DeptIds = Db.GetIQueryable<Base_UserDepartment>().Where(s => s.UserID == aUser.Id).Select(x => x.DepartmentID).ToList();
                    //补充用户打印机列表
                    StringBuilder sqlStr = new StringBuilder();
                    sqlStr.Append("select ");
                    sqlStr.Append("m.Id,");
                    sqlStr.Append("m.Name,");
                    sqlStr.Append("m.Type,");
                    sqlStr.Append("t.Type TypeName,");
                    sqlStr.Append("ifnull(m.`Status`,0) Status ");
                    sqlStr.Append("from PB_Printer m ");
                    sqlStr.Append("inner join Base_User s on m.WorkShopID=s.DepartmentId ");
                    sqlStr.Append("inner join PB_PrinterType t on m.type=t.Id ");
                    sqlStr.Append("where ");
                    sqlStr.Append("s.DepartmentId ='" + aUser.DepartmentId + "' ");
                    sqlStr.Append("and s.UserName='" + aUser.UserName + "'");
                    aUser.PrinterList = Db.GetListBySql<Printers>(sqlStr.ToString());
                    aUser.Printer = "";
                });

            }
        }

        public async Task<List<UserRole>> GetUserRoleDataListAsync(PageInput<ConditionDTO> input)
        {
            List<UserRole> userRoles = new List<UserRole>();
            Expression<Func<Base_UserRole, Base_User, UserRoleDTO>> select = (a, b) => new UserRoleDTO
            {
                Id = b.Id,
                Name = b.RealName,
                RoleId=a.RoleId
            };
            var search = input.Search;
            select = select.BuildExtendSelectExpre();
            var q_User = Db.GetIQueryable<Base_UserRole>();
            var q = from a in q_User.AsExpandable()
                    join b in Db.GetIQueryable<Base_User>() on a.UserId equals b.Id into ab
                    from b in ab.DefaultIfEmpty()
                    select @select.Invoke(a, b);
        
            if (search.Roid.Count>0)
            {
                List<string> vs = new List<string>();

                foreach (var key in search.Roid) {
                    vs.Add(key);
                }

                q = q.Where(m => vs.Contains(m.RoleId));

            }
            
            var ITEM=await q.Select(s=>new { s.Id,s.Name}).Distinct().ToListAsync();
            foreach (var item in ITEM.ToList()) {
                UserRole userRole = new UserRole();
                userRole.Id = item.Id;
                userRole.Name = item.Name;
                userRoles.Add(userRole);
            }

            return userRoles;
        }

        public async Task<PageResult<Base_UserDTO>> GetDataListAsyncUser(PageInput<Base_UsersInputDTO> input)
        {
            Expression<Func<Base_User, Base_Department, Base_Department, Base_UserRole, Base_Role, Base_UserDTO>> select = (a, b, c, d, e) => new Base_UserDTO
            {
                DepartmentName = b.Name,
                SupplierId =b.SupplierId,
                FactoryName = c.Name,
                RowName = e.RoleName,
            };
            var search = input.Search;
            select = select.BuildExtendSelectExpre();
            var q_User = search.all ? Db.GetIQueryable<Base_User>() : GetIQueryable();
            var q = from a in q_User.AsExpandable()
                    join b in Db.GetIQueryable<Base_Department>() on a.DepartmentId equals b.Id into ab
                    from b in ab.DefaultIfEmpty()
                    join c in Db.GetIQueryable<Base_Department>() on a.FactoryId equals c.Id into ac
                    from c in ac.DefaultIfEmpty()
                    join d in Db.GetIQueryable<Base_UserRole>() on a.Id equals d.UserId into ad
                    from d in ad.DefaultIfEmpty()
                    join e in Db.GetIQueryable<Base_Role>() on d.RoleId equals e.Id into de
                    from e in de.DefaultIfEmpty()
                    select @select.Invoke(a, b, c, d, e);
            if (!search.keyword.IsNullOrEmpty())
            {
                var keyword = $"%{search.keyword}%";
                q = q.Where(x =>
                      EF.Functions.Like(x.UserName, keyword)
                      || EF.Functions.Like(x.RealName, keyword));
            }
            q = q.Where(m => _operator.Property.DeptIds.Contains(m.FactoryId));
            return await q.GetPageResultAsync(input);


        }
        public async Task<Base_UserDTO> GetDataDingUserIdAsyncUser(string DingUserId)
        {
            Expression<Func<Base_User, Base_Department, Base_Department, Base_UserRole, Base_Role, Base_UserDTO>> select = (a, b, c, d, e) => new Base_UserDTO
            {
                DepartmentName = b.Name,
                SupplierId = b.SupplierId,
                FactoryName = c.Name,
                RowName = e.RoleName,
                HeadImg =  a.HeadImg ==null? "https://gimg2.baidu.com/image_search/src=http%3A%2F%2Fc-ssl.duitang.com%2Fuploads%2Fitem%2F201912%2F25%2F20191225224833_zloky.thumb.400_0.jpg&refer=http%3A%2F%2Fc-ssl.duitang.com&app=2002&size=f9999,10000&q=a80&n=0&g=0n&fmt=jpeg?sec=1641014763&t=e504a9f006f0bef005dd99955758451f" : a.HeadImg
            };
            
            select = select.BuildExtendSelectExpre();
           
            var q = from a  in GetIQueryable().AsExpandable()
                    join b in Db.GetIQueryable<Base_Department>() on a.DepartmentId equals b.Id into ab
                    from b in ab.DefaultIfEmpty()
                    join c in Db.GetIQueryable<Base_Department>() on a.FactoryId equals c.Id into ac
                    from c in ac.DefaultIfEmpty()
                    join d in Db.GetIQueryable<Base_UserRole>() on a.Id equals d.UserId into ad
                    from d in ad.DefaultIfEmpty()
                    join e in Db.GetIQueryable<Base_Role>() on d.RoleId equals e.Id into de
                    from e in de.DefaultIfEmpty()
                    select @select.Invoke(a, b, c, d, e);
            q = q.Where(m => m.DingUserId==DingUserId);
            return await q.FirstOrDefaultAsync();


        }
        public async Task<PageResult<Base_User>> GetDataListAsyncs(PageInput<ConditionDTO> input)
        {
            var q = GetIQueryable();
            var where = LinqHelper.True<Base_User>();
            var search = input.Search;
            //筛选
            if (!search.Keyword.IsNullOrEmpty())
            {
                var newWhere = DynamicExpressionParser.ParseLambda<Base_User, bool>(
                    ParsingConfig.Default, false, $@"UserName.Contains(@0) or RealName.Contains(@0)", search.Keyword);
                where = where.And(newWhere);
            }
            //where = where.And(x => x.DepartmentId == _operator.Property.DepartmentId);
            //where = where.And(x => _operator.Property.DeptIds.Contains(x.DepartmentId));
            return await q.Where(where).GetPageResultAsync(input);
        }

        public async Task<Base_UserDTO> GetTheDataAsync(string id)
        {
            if (id.IsNullOrEmpty())
                return null;
            else
            {
                PageInput<Base_UsersInputDTO> input = new PageInput<Base_UsersInputDTO>
                {
                    Search = new Base_UsersInputDTO
                    {
                        all = true,
                        userId = id
                    }
                };
                return (await GetDataListAsync(input)).Data.FirstOrDefault();
            }
        }

        [DataAddLog(UserLogType.系统用户管理, "UserCode", "用户编号")]
        [DataRepeatValidate(new string[] { "UserName" ,"UserCode" },  new string[] { "用户名","用户编号" })]

        public async Task AddDataAsync(UserEditInputDTO input)
        {
            input.EmployeStatus = false;
            string QrCdeo = h_User + "," + input.Id + "," + input.DepartmentId;
            input.QrCode = QrCdeo;
            await InsertAsync(_mapper.Map<Base_User>(input));
            await SetUserRoleAsync(input.Id, input.RoleIdList);
        }

        [DataEditLog(UserLogType.系统用户管理, "UserCode", "用户编号")]
       
        public async Task UpdateDataAsync(UserEditInputDTO input)
        {
            List<string> RoleIdListInfo = input.RoleIdList;
            input.RoleIdList = null;
            input.newPwd = null;
            input.FactoryId = input.FactoryId;
            List<string> props = GetFieldList(input);

            string QrCdeo = h_User + "," + input.Id + "," + input.DepartmentId;
            input.QrCode = QrCdeo;
            if (input.Id == GlobalData.ADMINID && _operator?.UserId != input.Id)
                throw new BusException("禁止更改超级管理员！");
            await UpdateAsync(_mapper.Map<Base_User>(input), props);
            input.RoleIdList = RoleIdListInfo;
            await SetUserRoleAsync(input.Id, input.RoleIdList);
            //_mapper.Map<>(input)
            await _userCache.UpdateCacheAsync(input.Id);
        }

        [DataDeleteLog(UserLogType.系统用户管理, "RealName", "用户")]
        public async Task DeleteDataAsync(List<string> ids)
        {
            if (ids.Contains(GlobalData.ADMINID))
                throw new BusException("超级管理员是内置账号,禁止删除！");

            await DeleteAsync(ids);

            await _userCache.UpdateCacheAsync(ids);
        }
        [Transactional]
        public async Task UpdateImgAsync(Base_User input)
        {
            await ExecuteSqlAsync(" UPDATE Base_User SET HeadImg='" + input.HeadImg + "' WHERE Id='" + input.Id + "' ");

        }

        //递归查询部门下所有信息
        private List<string> GetItem(string Parentid, List<string> liststr, List<Base_Department> listdata)
        {
            var itemlist = listdata.Where(x => x.ParentId == Parentid).ToList();
            foreach (var item in itemlist)
            {
                liststr.Add(item.Id);
                GetItem(item.Id, liststr, listdata);
            }
            return liststr;
        }
        public async Task<List<UserRoleImage>> GetDataListByDeptuserid( PageInput<ConditionDTO> input)
        {
            List<UserRoleImage> userRoles = new List<UserRoleImage>();
            Expression<Func<Base_User, Base_Department, Base_UserRole, Base_UserDTO>> select = (a, b,c) => new Base_UserDTO
            {
                DepartmentName = b.Name,
                Roid=c.RoleId
            };
            select = select.BuildExtendSelectExpre();
            var q = from a in GetIQueryable().AsExpandable()
                    join b in Db.GetIQueryable<Base_Department>() on a.DepartmentId equals b.Id into ab
                    from b in ab.DefaultIfEmpty()
                    join c in Db.GetIQueryable<Base_UserRole>() on a.Id equals c.UserId into ac
                    from c in ac.DefaultIfEmpty()
                    select @select.Invoke(a, b,c);
                List<string> liststr = new List<string>();
                List<Base_Department> listdata = await Db.GetIQueryable<Base_Department>().ToListAsync();
            if (listdata==null) {
                throw new BusException("");
            }
            var typelist = listdata.Where(x => x.ParentId == input.Search.Keyword).ToList();
            if (typelist.Count > 0)
            {

                foreach (var item in typelist)
                {
                    liststr.Add(input.Search.Keyword);
                    liststr.Add(item.Id);
                    GetItem(item.Id, liststr, listdata);
                }
                q = q.Where(w => liststr.Contains(w.DepartmentId));
            }
            else {
                q = q.Where(w=>w.DepartmentId== input.Search.Keyword);
            }
            if (!input.Search.Roid.IsNullOrEmpty())
            {
                if (input.Search.Roid.Count>0) {
                    
                    List<string> vs = new List<string>();
                    foreach (var key in input.Search.Roid)
                    {
                        vs.Add(key);
                    }
                    q = q.Where(m => vs.Contains(m.Roid));
                }
               
            }
            if (!input.Search.Condition.IsNullOrEmpty())
            {
                q = q.Where(w => w.RealName.Contains(input.Search.Condition));
            }
            q = q.Where(m => m.EmployeStatus == false);
            var ITEM = await q.Select(s => new { s.Id, s.RealName,s.HeadImg }).Distinct().ToListAsync();
            foreach (var item in ITEM.ToList())
            {
                UserRoleImage userRole = new UserRoleImage();
                userRole.Id = item.Id;
                userRole.RealName = item.RealName;
                userRole.HeadImg = item.HeadImg;
                userRoles.Add(userRole);
            }
            return userRoles;
        }
        public async Task<List<Base_UserDTO>> SelectUserID(string ID)
        {
            Expression<Func<Base_User, Base_Department, Base_UserDTO>> select = (a, b) => new Base_UserDTO
            {
                DepartmentName = b.Name
            };
            select = select.BuildExtendSelectExpre();
            var q = from a in GetIQueryable().AsExpandable()
                    join b in Db.GetIQueryable<Base_Department>() on a.DepartmentId equals b.Id into ab
                    from b in ab.DefaultIfEmpty()
                    select @select.Invoke(a, b);
            q = q.Where(w => w.DepartmentId == ID);
            var res = await q.ToListAsync();

            return res;
        }
        public async Task<List<Base_UserDTO>> Selectid(string id)
        {
            Expression<Func<Base_User, Base_Department, Base_UserDTO>> select = (a, b) => new Base_UserDTO
            {
                DepartmentName = b.Name
            };
            select = select.BuildExtendSelectExpre();
            var q = from a in GetIQueryable().AsExpandable()
                    join b in Db.GetIQueryable<Base_Department>() on a.DepartmentId equals b.Id into ab
                    from b in ab.DefaultIfEmpty()
                    select @select.Invoke(a, b);
            string[] arr = id.Split(',');
            List<string> List = new List<string>();
            foreach (var item in arr)
            {
                List.Add(item);
            }
            q = q.Where(m => List.Contains(m.Id));
            var res = await q.ToListAsync();
            return res;
        }
        public async Task<List<Base_UserDTO>> SelectUser()
        {
            Expression<Func<Base_User, Base_Department, Base_UserDTO>> select = (a, b) => new Base_UserDTO
            {
                DepartmentName = b.Name
            };
            select = select.BuildExtendSelectExpre();
            var q = from a in GetIQueryable().AsExpandable()
                    join b in Db.GetIQueryable<Base_Department>() on a.DepartmentId equals b.Id into ab
                    from b in ab.DefaultIfEmpty()
                    select @select.Invoke(a, b);


            var res = await q.ToListAsync();

            return res;
        }
        public async Task<List<UserTreeDTO>> GetTreeUserListAsyncs()
        {
            //获取组织信息
            var list = await Db.GetIQueryable<Base_Department>().ToListAsync();
            List<UserTreeDTO> listData = new List<UserTreeDTO>();
            foreach (var item in list)
            {
                UserTreeDTO tree = new UserTreeDTO();
                tree.Id = item.Id;
                tree.ParentId = item.ParentId;
                tree.Text = item.Name;
                tree.Value = item.Id;
                listData.Add(tree);
                await GetItemTree(item.Id, listData);
            }
            var treeList = listData
                .Select(x => new UserTreeDTO
                {
                    Id = x.Id,
                    ParentId = x.ParentId,
                    Text = x.Text,
                    Value = x.Id,
                }).ToList();
            return TreeHelper.BuildTree(treeList);
        }
        protected async Task<List<UserTreeDTO>> GetItemTree(string ParentId, List<UserTreeDTO> ListData)
        {
            var childrenItem = await Db.GetIQueryable<Base_User>().Where(x => x.DepartmentId == ParentId).ToListAsync();

            foreach (var item in childrenItem)
            {
                UserTreeDTO treedata = new UserTreeDTO();
                treedata.Id = item.Id;
                treedata.ParentId = item.DepartmentId;
                treedata.Text = item.RealName;
                treedata.Value = item.Id;
                ListData.Add(treedata);
            }
            return ListData;

        }


        /// <summary>
        /// 获取车间的工厂Id
        /// </summary>
        /// <returns></returns>
        public async Task<DeptData> GetOperatorGongChang(string workshopid)
        {
            string deptId = string.Empty;
            var deptdata = await Db.GetIQueryable<Base_Department>().Where(x => x.Id == workshopid).FirstOrDefaultAsync();
            if (deptdata==null) {
                throw new BusException("请求异常");
            }
            if (deptdata.Type == 7 || deptdata.Type == 8)
            {
                deptId = deptdata.Id;
            }
            else
            {
                if (deptId.IsNullOrEmpty())
                {
                    string parentId = deptdata.ParentId;
                    do
                    {
                        var data = await Db.GetIQueryable<Base_Department>().Where(x => x.Id == parentId).FirstOrDefaultAsync();
                        if (data == null)
                        {
                            throw new BusException("请求异常");
                        }
                        if (data.Type == 7 || data.Type==8)
                        {
                            deptId = data.Id;
                        }
                        else
                        {
                            parentId = data.ParentId;
                        }
                    } while (deptId == "");
                }
            }
            deptdata = await Db.GetIQueryable<Base_Department>().Where(x => x.Id == deptId).FirstOrDefaultAsync();
            DeptData dept = new DeptData();
            dept.DetpId = deptdata.Id;
            dept.DeptName = deptdata.Name;
            dept.DeptType = deptdata.Type;
            return dept;
        }



        /// <summary>
        /// 获取操作者的法人组织id
        /// </summary>
        /// <returns></returns>
        public async Task<DeptData> GetOperatorDept()
        {
            string deptId = string.Empty;
            Base_User userdata = await Db.GetIQueryable<Base_User>().Where(x => x.Id == _operator.UserId).FirstOrDefaultAsync();
            var deptdata = await Db.GetIQueryable<Base_Department>().Where(x => x.Id == userdata.DepartmentId).FirstOrDefaultAsync();
            if (deptdata.Type == 1 || deptdata.Type == 8)
            {
                deptId = deptdata.Id;
            }
            else
            {
                if (deptId.IsNullOrEmpty())
                {
                    string parentId = deptdata.ParentId;
                    do
                    {
                        var data = await Db.GetIQueryable<Base_Department>().Where(x => x.Id == parentId).FirstOrDefaultAsync();
                        if (data.Type == 1 || data.Type == 8)
                        {
                            deptId = data.Id;
                        }
                        else
                        {
                            parentId = data.ParentId;
                        }
                    } while (deptId == "");
                }
            }
            deptdata = await Db.GetIQueryable<Base_Department>().Where(x => x.Id == deptId).FirstOrDefaultAsync();
            DeptData dept = new DeptData();
            dept.DetpId = deptdata.Id;
            dept.DeptName = deptdata.Name;
            dept.DeptType = deptdata.Type;
            return dept;
        }


        /// <summary>
        /// 获取操作者的工厂id
        /// </summary>
        /// <returns></returns>
        public async Task<DeptData> GetOperatorDeptGongchang()
        {
            string deptId = string.Empty;
            Base_User userdata = await Db.GetIQueryable<Base_User>().Where(x => x.Id == _operator.UserId).FirstOrDefaultAsync();
            var deptdata = await Db.GetIQueryable<Base_Department>().Where(x => x.Id == userdata.DepartmentId).FirstOrDefaultAsync();

            if (deptdata.Type == 1  )
            {
                deptId = deptdata.Id;
            } else if (deptdata.Type == 7 || deptdata.Type == 6) {
                deptId = deptdata.Id;
            }
            else
            {
                if (deptId.IsNullOrEmpty())
                {
                    string parentId = deptdata.ParentId;
                    do
                    {
                        var data = await Db.GetIQueryable<Base_Department>().Where(x => x.Id == parentId).FirstOrDefaultAsync();
                        if (data == null) {
                            throw new BusException("错误");
                        }

                        if (data.Type != 7 && data.Type != 6)
                        {
                            parentId = data.Id;
                            if (parentId == null)
                            {
                                throw new BusException("没找到！");
                            }
                        }
                        else
                        {
                            deptId = data.Id;
                        }
                    } while (deptId == "");
                }
            }
            deptdata = await Db.GetIQueryable<Base_Department>().Where(x => x.Id == deptId).FirstOrDefaultAsync();

            DeptData dept = new DeptData();
            dept.DetpId = deptdata.Id;
            dept.DeptName = deptdata.Name;
            dept.DeptType = deptdata.Type;
            return dept;
        }
        /// <summary>
        /// 获取操作者的工厂id
        /// </summary>
        /// <returns></returns>
        public async Task<DeptData> GetOperatorDeptFaren()
        {
            string deptId = string.Empty;
            Base_User userdata = await Db.GetIQueryable<Base_User>().Where(x => x.Id == _operator.UserId).FirstOrDefaultAsync();
            var deptdata = await Db.GetIQueryable<Base_Department>().Where(x => x.Id == userdata.DepartmentId).FirstOrDefaultAsync();

            if (deptdata.Type == 1)
            {
                deptId = deptdata.Id;
            }
            else
            {
                if (deptId.IsNullOrEmpty())
                {
                    string parentId = deptdata.ParentId;
                    do
                    {
                        var data = await Db.GetIQueryable<Base_Department>().Where(x => x.Id == parentId).FirstOrDefaultAsync();
                        if (data == null)
                        {
                            throw new BusException("错误");
                        }

                        if (data.Type != 7)
                        {
                            parentId = data.ParentId;
                            if (parentId == null)
                            {
                                throw new BusException("没找到！");
                            }
                        }
                        else
                        {
                            deptId = data.Id;
                        }
                    } while (deptId == "");
                }
            }
            deptdata = await Db.GetIQueryable<Base_Department>().Where(x => x.Id == deptId).FirstOrDefaultAsync();

            DeptData dept = new DeptData();
            dept.DetpId = deptdata.Id;
            dept.DeptName = deptdata.Name;
            dept.DeptType = deptdata.Type;
            return dept;
        }

        /// <summary>
        /// 获取操作者的部门信息
        /// </summary>
        /// <returns></returns>
        public async Task<DeptData> GetOperatorDeptType()
        {
            Base_User userdata = await Db.GetIQueryable<Base_User>().Where(x => x.Id == _operator.UserId).FirstOrDefaultAsync();
            var deptdata = await Db.GetIQueryable<Base_Department>().Where(x => x.Id == userdata.DepartmentId).FirstOrDefaultAsync();
            DeptData dept = new DeptData();
            dept.DetpId = deptdata.Id;
            dept.DeptName = deptdata.Name;
            dept.DeptType = deptdata.Type;
            dept.SupplierId = deptdata.SupplierId;
            return dept;
        }

        /// <summary>
        /// 获取登录人法人下所有的部门信息
        /// </summary>
        /// <returns></returns>
        public async Task<List<string>> GetDeptString()
        {
            string deptId = string.Empty;
            Base_User userdata = await Db.GetIQueryable<Base_User>().Where(x => x.Id == _operator.UserId).FirstOrDefaultAsync();
            var deptdata = await Db.GetIQueryable<Base_Department>().Where(x => x.Id == userdata.DepartmentId).FirstOrDefaultAsync();
            if (deptdata.Type == 1)
            {
                deptId = deptdata.Id;
            }
            else
            {
                if (deptId.IsNullOrEmpty())
                {
                    string parentId = deptdata.ParentId;
                    do
                    {
                        var data = await Db.GetIQueryable<Base_Department>().Where(x => x.Id == parentId).FirstOrDefaultAsync();
                        if (data.Type != 1)
                        {
                            parentId = data.ParentId;
                        }
                        else
                        {
                            deptId = data.Id;
                        }
                    } while (deptId == "");
                }
            }
            List<string> liststr = new List<string>();
            deptdata = await Db.GetIQueryable<Base_Department>().Where(x => x.Id == deptId).FirstOrDefaultAsync();
            liststr.Add(deptdata.Id);
            //获取所有的部门信息
            List<Base_Department> deptlist = await Db.GetIQueryable<Base_Department>().ToListAsync();
            var listdata = deptlist.Where(x => x.ParentId == deptdata.Id).ToList();
            foreach (var item in listdata)
            {
                liststr.Add(item.Id);
                GetDeptItem(item.Id, liststr, deptlist);
            }
            return liststr;
        }

        private List<string> GetDeptItem(string deptId, List<string> liststr, List<Base_Department> deptlist)
        {
            var dlist = deptlist.Where(x => x.ParentId == deptId).ToList();
            foreach (var item in dlist)
            {
                liststr.Add(item.Id);
                GetDeptItem(item.Id, liststr, deptlist);
            }
            return liststr;
        }

        /// <summary>
        /// 获取操作者法人下的所有仓库
        /// </summary>
        /// <returns></returns>
        public async Task<List<string>> GetStorString()
        {
            //获取登录人信息
            Base_User userdata = await Db.GetIQueryable<Base_User>().Where(x => x.Id == _operator.UserId).FirstOrDefaultAsync();
            List<Base_Department> Departmentdata = await Db.GetIQueryable<Base_Department>().ToListAsync();
            var deptlist = Departmentdata.Where(x => x.ParentId == userdata.FactoryId).ToList();
            List<string> liststr = new List<string>();
            foreach (var item in deptlist)
            {
                if (item.Type == 2)
                {
                    liststr.Add(item.Id);
                }
                GeStorItem(item.Id, liststr, Departmentdata);
            }
            return liststr;

        }

        /// <summary>
        /// 递归查找工厂下所有的仓库
        /// </summary>
        /// <param name="deptId">组织Id</param>
        /// <param name="deptlist">是仓库的集合</param>
        /// <param name="Departmentdata">组织数据</param>
        /// <returns></returns>
        private List<string> GeStorItem(string deptId, List<string> deptlist, List<Base_Department> Departmentdata)
        {
            var dlist = Departmentdata.Where(x => x.ParentId == deptId).ToList();
            foreach (var item in dlist)
            {
                if (item.Type == 2)
                {
                    deptlist.Add(item.Id);
                }
                GeStorItem(item.Id, deptlist, Departmentdata);
            }
            return deptlist;
        }

        /// <summary>
        /// 获取登录人所属工厂下所有的仓库信息
        /// </summary>
        /// <param name="DeptId">操作者的工厂Id</param>
        /// <returns></returns>
        public async Task<List<string>> GetStorList(string DeptId)
        {
            List<Base_Department> Departmentdata = await Db.GetIQueryable<Base_Department>().ToListAsync();
            var deptlist = Departmentdata.Where(x => x.ParentId == DeptId).ToList();
            List<string> liststr = new List<string>();
            foreach (var item in deptlist)
            {
                if (item.Type == 2)
                {
                    liststr.Add(item.Id);
                }
                GeStorItem(item.Id, liststr, Departmentdata);
            }
            return liststr;
        }

        /// <summary>
        /// 获取登录人所属工厂下所有的车间信息
        /// </summary>
        /// <param name="DeptId">操作者的工厂Id</param>
        /// <returns></returns>
        public async Task<List<string>> GetWorkshopString(string DeptId)
        {
            List<Base_Department> Departmentdata = await Db.GetIQueryable<Base_Department>().ToListAsync();
            var deptlist = Departmentdata.Where(x => x.ParentId == DeptId).ToList();
            List<string> liststr = new List<string>();
            foreach (var item in deptlist)
            {
                if (item.Type == 3)
                {
                    liststr.Add(item.Id);
                }
                GeWorkshopItem(item.Id, liststr, Departmentdata);
            }
            return liststr;
        }
        /// <summary>
        /// 获取登录人所属工厂下所有的车间信息
        /// </summary>
        /// <param name="DeptId">操作者的工厂Id</param>
        /// <returns></returns>
        public async Task<List<string>> GetBumenString(string DeptId)
        {
           
            List<Base_Department> Departmentdata = await Db.GetIQueryable<Base_Department>().ToListAsync();
            var deptlist = Departmentdata.Where(x => x.ParentId == DeptId).ToList();
            List<string> liststr = new List<string>();
            foreach (var item in deptlist)
            {
                if (item.Type == 6)
                {
                    liststr.Add(item.Id);
                }
                GeBumenItem(item.Id, liststr, Departmentdata);
            }
            return liststr;
        }
        /// <summary>
        /// 递归查找工厂下所有的车间
        /// </summary>
        /// <param name="deptId">组织Id</param>
        /// <param name="deptlist">是仓库的集合</param>
        /// <param name="Departmentdata">组织数据</param>
        /// <returns></returns>
        private List<string> GeWorkshopItem(string deptId, List<string> deptlist, List<Base_Department> Departmentdata)
        {
            var dlist = Departmentdata.Where(x => x.ParentId == deptId).ToList();
            foreach (var item in dlist)
            {
                if (item.Type == 3)
                {
                    deptlist.Add(item.Id);
                }
                GeWorkshopItem(item.Id, deptlist, Departmentdata);
            }
            return deptlist;
        }
        /// <summary>
        /// 递归查找工厂下所有的车间
        /// </summary>
        /// <param name="deptId">组织Id</param>
        /// <param name="deptlist">是仓库的集合</param>
        /// <param name="Departmentdata">组织数据</param>
        /// <returns></returns>
        private List<string> GeBumenItem(string deptId, List<string> deptlist, List<Base_Department> Departmentdata)
        {
            var dlist = Departmentdata.Where(x => x.ParentId == deptId).ToList();
            foreach (var item in dlist)
            {
                if (item.Type == 6)
                {
                    deptlist.Add(item.Id);
                }
                GeBumenItem(item.Id, deptlist, Departmentdata);
            }
            return deptlist;
        }

        /// <summary>
        /// 获取登录人部门下所有deptId
        /// </summary>
        /// <returns></returns>
        public async Task<List<string>> GetDeptIds()
        {
            List<string> liststr = new List<string>();
            //获取登录人信息
            Base_User userdata = await Db.GetIQueryable<Base_User>().Where(x => x.Id == _operator.UserId).FirstOrDefaultAsync();
            liststr.Add(userdata.DepartmentId);
            List<Base_Department> Departmentdata = await Db.GetIQueryable<Base_Department>().ToListAsync();
            var deptlist = Departmentdata.Where(x => x.ParentId == userdata.DepartmentId).ToList();
            foreach (var item in deptlist)
            {
                liststr.Add(item.Id);
                GetDeptItem(item.Id, liststr, deptlist);
            }
            return liststr;
        }

        /// <summary>
        /// 获取登录人工厂下所有deptId
        /// </summary>
        /// <returns></returns>
        public async Task<List<string>> GetFactoryIds()
        {
            List<string> liststr = new List<string>();
            //获取登录人信息
            Base_User userdata = await Db.GetIQueryable<Base_User>().Where(x => x.Id == _operator.UserId).FirstOrDefaultAsync();
            liststr.Add(userdata.DepartmentId);
            List<Base_Department> Departmentdata = await Db.GetIQueryable<Base_Department>().ToListAsync();
            var deptlist = Departmentdata.Where(x => x.ParentId == userdata.FactoryId).ToList();
            foreach (var item in deptlist)
            {
                liststr.Add(item.Id);
                GetDeptItem(item.Id, liststr, Departmentdata);
            }
            return liststr;
        }

        #endregion

        #region 私有成员

        #endregion

        private async Task SetUserRoleAsync(string userId, List<string> roleIds)
        {
            roleIds = roleIds ?? new List<string>();
            var userRoleList = roleIds.Select(x => new Base_UserRole
            {
                Id = IdHelper.GetId(),
                CreateTime = DateTime.Now,
                UserId = userId,
                RoleId = x
            }).ToList();
            await Db.DeleteAsync<Base_UserRole>(x => x.UserId == userId);
            await Db.InsertAsync(userRoleList);
        }

        public async Task<DeptData> GetOperatorDeptBumenId()
        {
            string deptId = string.Empty;
            Base_User userdata = await Db.GetIQueryable<Base_User>().Where(x => x.Id == _operator.UserId).FirstOrDefaultAsync();
            var deptdata = await Db.GetIQueryable<Base_Department>().Where(x => x.Id == userdata.DepartmentId).FirstOrDefaultAsync();
            if (deptdata.Type == 7)
            {
                deptId = deptdata.Id;
            }
            else
            {
                if (deptId.IsNullOrEmpty())
                {
                    string parentId = deptdata.ParentId;
                    do
                    {
                        var data = await Db.GetIQueryable<Base_Department>().Where(x => x.Id == parentId).FirstOrDefaultAsync();
                        if (data == null)
                        {
                            throw new BusException("没找到！");
                        }
                        if (data.Type != 7)
                        {
                            parentId = data.ParentId;

                        }
                        else
                        {
                            deptId = data.Id;
                        }
                    } while (deptId == "");
                }

            }
            deptdata = await Db.GetIQueryable<Base_Department>().Where(x => x.Id == deptId).FirstOrDefaultAsync();

            DeptData dept = new DeptData();
            dept.DetpId = deptdata.Id;
            dept.DeptName = deptdata.Name;
            dept.DeptType = deptdata.Type;
            return dept;
        }

        public async Task<List<Base_UserItemDTO>> GetItemUserList(string Deptid)
        {

            List<String> Rololist = new List<string>();
            List<String> RoloStr = new List<string>();
            //获取班组长信息
            var base_user =await Db.GetIQueryable<Base_User>().Where(m=>m.Id==Deptid).FirstOrDefaultAsync();
            //获取角色集合
            var rololist =await Db.GetIQueryable<Base_UserRole>().Where(m=>m.UserId==base_user.Id).ToListAsync();
            foreach (var item in rololist) {
                RoloStr.Add(item.RoleId);
            }
            foreach (var rolostr in RoloStr) {
                var tolist =await Db.GetIQueryable<Base_UserRole>().Where(m => m.RoleId == rolostr).ToListAsync();
                foreach (var itmes in tolist) {
                    Rololist.Add(itmes.UserId);
                }
            }
            Expression<Func<Base_User, Base_Department, PB_ScheduleDetail, PB_ShiftType, Base_UserItemDTO>> select = (a, b,c,d) => new Base_UserItemDTO
            {
                DepartmentName = b.Name,
                dispatchDate=c.WorkDate,
                TempId=d.Id,
                TempNmae=d.Name,
            };
            select = select.BuildExtendSelectExpre();
            var q = from a in GetIQueryable().AsExpandable()
                    join b in Db.GetIQueryable<Base_Department>() on a.DepartmentId equals b.Id into ab
                    from b in ab.DefaultIfEmpty()
                    join c in Db.GetIQueryable<PB_ScheduleDetail>() on a.Id equals c.UserId into ac
                    from c in ac.DefaultIfEmpty()
                    join d in Db.GetIQueryable<PB_ShiftType>() on c.Type equals d.Id into cd
                    from d in cd.DefaultIfEmpty()
                    select @select.Invoke(a, b,c,d);
            List<string> liststr = new List<string>();
            List<Base_Department> listdata = await Db.GetIQueryable<Base_Department>().ToListAsync();
            if (listdata == null)
            {
                throw new BusException("");
            }
            q = q.Where(m=> Rololist.Contains(m.Id));
            DateTime Time = Convert.ToDateTime(DateTime.Now.ToString("yyyy-MM-dd"));
           q = q.Where(m => m.dispatchDate== Time);  
            q = q.Where(m => m.EmployeStatus == false);
            var res = await q.ToListAsync();
            return res;
        }

        public async Task UploadAvatar(UserImgFile Data)
        {
            var user = await Db.GetIQueryable<Base_User>().Where(m => m.Id == Data.UserId).FirstOrDefaultAsync();

            if (user != null)
            {
                Base_User base_User = new Base_User();
                base_User.Id = user.Id;
                base_User.CreateTime = user.CreateTime;
                base_User.CreatorId = user.CreatorId;
                base_User.Deleted = user.Deleted;
                base_User.UserCode = user.UserCode;
                base_User.UserName = user.UserName;
                base_User.UserPost = user.UserPost;
                base_User.Password = user.Password;
                base_User.QrCode = user.QrCode;
                base_User.RealName = user.RealName;
                base_User.Sex = user.Sex;
                base_User.Birthday = user.Birthday;
                base_User.FactoryId = user.FactoryId;
                base_User.DepartmentId = user.DepartmentId;
                base_User.HeadImg = Data.ImgPush;
                base_User.EmployeStatus = user.EmployeStatus;
                base_User.Telephone = user.Telephone;
                base_User.DingUserId = user.DingUserId;
                base_User.WorkType = user.WorkType;
                await Db.UpdateAsync(base_User);
            }

        }

        /// <summary>
        /// 获取全局变量
        /// </summary>
        /// <param name="LinkType">全局变量码</param>
        /// <returns></returns>
        public async Task<Base_LinkType> GetLinkType(string LinkType)
        {
            Base_LinkType LinkTypeData = await Db.GetIQueryable<Base_LinkType>().Where(x => x.LinkType == LinkType).FirstOrDefaultAsync();
            return LinkTypeData;
        }

    }
}